package com.zeng.sboot.video;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class VideoDemo {

    public static final String ffmpeg_path = "E:\\ffmpeg-20200601-dd76226-win64-static\\bin\\ffmpeg.exe";//ffmpeg的安装位置
    public static final String video_path = "E:\\20191231_143242.mp4";
    public static final String mp4_name = "20191231_143242_transform.mp4";
    public static final String mp4folder_path = "E:/FfmpegTest/Movies/test1/";

    ProcessBuilder pb = new ProcessBuilder();

    public void test1() {
        ProcessBuilder pb = new ProcessBuilder();
        List<String> c = Arrays.asList("ffmpeg", "-version");//OK
        pb.command(c);


        try {
            pb.redirectErrorStream(true);
            Process p = pb.start();
            InputStream inputStream = p.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "GBK"));

            String rc = null;
            while ((rc = br.readLine()) != null) {
                System.out.println(rc);
            }

            inputStream.close();
            br.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void test2() {
        List<String> command = new ArrayList<>();
        command.add(ffmpeg_path);
        command.add("-i");
        command.add("E:\\20191231_143242.mp4");
        command.add("E:\\20191231_143242_2.avi");
        pb.redirectErrorStream(true);
        pb.command(command);

        try {
            Process process = pb.start();

            InputStream is = process.getInputStream();
            byte[] b = new byte[1024];
            while (is.read(b) != -1) {
                System.out.println(new String(b,0,b.length));
            }

            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void test3() {

        // 第一步：先将avi视频转成mp4
        // ffmpeg.exe -i  lucene.avi -c:v libx264 -s 1280x720 -pix_fmt yuv420p -b:a 63k -b:v 753k -r 18  .\lucene.mp4
        // ffmpeg.exe -i  e:/lucene.avi -c:v libx264 -s 1280x720 -pix_fmt yuv420p -b:a 63k -b:v 753k -r 18  e:/ffmpegtest/lucene.mp4
        List<String> command = new ArrayList<>();

        command.add(ffmpeg_path);
        command.add("-i");
        command.add("E:\\lucene.avi");
        command.add("-y");//覆盖输出文件
        command.add("-c:v");//-c:v 视频编码为x264 ，x264编码是H264的一种开源编码格式
        command.add("libx264");
        command.add("-s");//-s 设置分辨率
        command.add("1280x720");
        command.add("-pix_fmt");//-pix_fmt yuv420p：设置像素采样方式，主流的采样方式有三种，YUV4:4:4，YUV4:2:2，YUV4:2:0，它的作用是 根据采样方式来从码流中还原每个像素点的YUV（亮度信息与色彩信息）值
        command.add("yuv420p");
        command.add("-b:a");//-b 设置码率，-b:a和-b:v分别表示音频的码率和视频的码率，-b表示音频加视频的总码率。码率对一个视频质量有 很大的作用.
        command.add("63k");
        command.add("-b:v");
        command.add("753k");
        command.add("-r");//-r：帧率，表示每秒更新图像画面的次数，通常大于24肉眼就没有连贯与停顿的感觉了
        command.add("18");
        command.add("E:\\ffmpegtest\\lucene.mp4");
        pb.command(command);

        //将标准输入流和错误输入流合并，通过标准输入流读取信息         
        pb.redirectErrorStream(true);

        byte[] b = new byte[1024];

        try {
            Process process = pb.start();
            InputStream is = process.getInputStream();

            while (is.read(b) != -1) {
                System.out.println(new String(b,0,b.length));
            }
            System.out.println("MP4 转换完成");

        } catch (IOException e) {
            e.printStackTrace();
        }

        // 第二步：将mp4生成m3u8
        // ffmpeg -i  lucene.mp4   -hls_time 10 -hls_list_size 0  -hls_segment_filename  ./hls/lucene_%05d.ts ./hls/lucene.m3u8
        // ffmpeg -i  lucene.mp4   -hls_time 10 -hls_list_size 0  -hls_segment_filename  ./hls/lucene_%05d.ts ./hls/lucene.m3u8

        List<String> c2 = new ArrayList<>();
        c2.add(ffmpeg_path);
        c2.add("-i");
        c2.add("E:\\ffmpegtest\\lucene.mp4");
        c2.add("-hls_time");//-hls_time 设置每片的长度，单位为秒
        c2.add("10");
        c2.add("-hls_list_size");//-hls_list_size n: 保存的分片的数量，设置为0表示保存所有分片
        c2.add("0");
        c2.add("-hls_segment_filename");
        c2.add("E:/ffmpegtest/hls/lucene_%05d.ts");//-hls_segment_ﬁlename ：段文件的名称，%05d表示5位数字
        c2.add("E:/ffmpegtest/hls/lucene.m3u8");
        //生成的效果是：将lucene.mp4视频文件每10秒生成一个ts文件，最后生成一个m3u8文件，m3u8文件是ts的索引 文件
        pb.command(c2);

        try {
            Process p2 = pb.start();
            InputStream is2 = p2.getInputStream();

            while (is2.read(b) != -1) {
                System.out.println(new String(b, 0, b.length));
            }

            System.out.println("ok....");

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        VideoDemo demo = new VideoDemo();

        //demo.test1();
        //demo.test2();
        demo.test3();
    }
}
